現在這個全球化的社會,特別是軟體的世界,應該很少軟體應用程式只顯示一種語言了吧。
就算軟體主要的受眾是台灣人,除了繁體中文以外,最起碼還要提供英文版,好讓在台外國人可以操作和使用。讓你的應用程式說上各國的語言,是良好使用者體驗一個很重要的關鍵。
Qt 提供了一套相當完整的多國語言實作機制。要實現多國語言,我們會先了解最關鍵的 tr()
函數,接著與兩大模組打交道:QTranslator 和 lupdate/lrelease 工具。
以下我們用一個 Qt 專案來做示範。這支程式極度簡潔,只有一個文字標籤 (QLabel):
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QLabel label = new QLabel(QObject::tr("Hello World!"));
label.show();
return app.exec();
}
你可能注意到了,我們在設置文字標籤的字串 "Hello World!" 時,用了 QObject::tr() 把文字包起來。
QObject::tr()
函數是 Qt 多國語言的關鍵,目的就是告訴 Qt:這個字串需要被翻譯成多國語言喔!
你可以把 QObject::tr() 想像成查詢字典。當應用程式進行多國語言切換時,QObject::tr() 函數會拿傳入的字串去查詢一張翻譯對照表,並回傳對應語言的字串。比如說,當應用程式切換成繁體中文時,傳入參數 "Hello World!" 就會回傳 「你好,世界!」。這樣就可以達成多國語言顯示的目的了。
要特別注意一點,QObject::tr() 裡面一定只能放字面常量,不能放變數。
QObject::tr("我是字面常量"); // 可以
QString str01 = "我是字串變數";
QObject::tr(str01); // <= 這樣是不行的喔!
多國語言的第一步,就是把原始碼裡面所有的字串都用 tr() 函數包起來。
下一個問題就是,怎麼產生這張翻譯字串對照表呢?
Qt 提供了 lupdate 工具來從你的原始碼中提取這些字串。lupdate 會掃過專案中的程式碼,把所有被 tr() 標記的字串擷取出來,生成一個.ts檔案。這個檔案你可以用 Qt 提供的 Linguist 工具來打開,完成各語言的翻譯。
執行 lupdate 之前,要先在 .pro 專案檔裡面指定.ts檔案名稱。
SOURCES = main.cpp
TRANSLATIONS = my_translation.ts
接著執行 lupdate 指令。該程式位於 Qt 安裝目錄下,使用方式如下:
lupdate your_project.pro
執行成功之後,用文字編輯器去打開 my_translation.ts 會發現,原來就是個 XML 呀!
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE TS>
<TS version="2.1">
<context>
<name>QObject</name>
<message>
<location filename="main.cpp" line="9"/>
<source>Hello World!</source>
<translation type="unfinished"></translation>
</message>
</context>
</TS>
接著你可以用 Qt 提供的 Linguist 工具打開 my_translation.ts 檔案,就可以每個字串逐個翻譯囉。
翻譯完成後,我們需要將.ts轉換成.qm才能為 Qt 應用程式使用。這兩種檔案的差別在於:.ts 是人類可讀的XML純文字檔案,但是 .qm (Qt message file format) 則是專門優化成可以進行快速字串查詢的二進位檔。
你可以用命令列工具 lrelease 將 .ts 檔案轉換為 .qm 檔案,也可以直接用 Linguist 的選單 "File" -> "Release",來另存成 .qm 檔案。
最後一步,就是要讓 Qt 應用程式使用翻譯完成的 .qm 檔案囉。
這是我們要用的是 QTranslator 翻譯類別,它能載入.qm檔案來提供翻譯的資源。
#include <QTranslator>
...
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QTranslator translator;
translator.load("path/to/my_translation.qm");
app.installTranslator(&translator);
QLabel* label = new QLabel(QObject::tr("Hello World!"));
label->show();
return app.exec();
}
我們呼叫了 QTranslator 的成員方法 load() 來載入.qm檔案,接著呼叫 QApplication::installTranslator() 來安裝語言翻譯。這樣應用程式就會翻譯所有用到tr()的字串囉。
這樣執行程式,看看有沒有出現翻譯吧!